import CryptoJS from 'crypto-js';

type ChatMessage = { role: 'system' | 'user' | 'assistant'; content: string };

export class SparkChatService {
    private readonly APPID = 'd543b718';
    private readonly APISecret = 'Yzc0OGNkMWV...请替换为完整值';
    private readonly APIKey = '207ed48aee93105b76629a209399ef1c';
    private readonly host = 'spark-api.xf-yun.com';
    private readonly path = '/v3.5/chat';
    private readonly domain = 'generalv3.5';

    async getReply(userText: string, history: ChatMessage[] = []): Promise<string> {
        // 星火要求对 authorization 做 urlencode
        const url = `wss://${this.host}${this.path}?${this.authQuery(true)}`;
        return new Promise<string>((resolve, reject) => {
            const ws = new WebSocket(url);
            let reply = '';

            ws.onopen = () => {
                const payload = {
                    header: { app_id: this.APPID },
                    parameter: { chat: { domain: this.domain, temperature: 0.6, max_tokens: 1024 } },
                    payload: {
                        message: {
                            text: [...history, { role: 'user', content: userText }]
                        }
                    }
                };
                ws.send(JSON.stringify(payload));
            };

            ws.onmessage = (e) => {
                const data = JSON.parse(e.data);
                if (data.header?.code !== 0) {
                    console.error('[Spark] 错误:', data.header);
                    reject(new Error(data.header?.message || 'Spark错误'));
                    ws.close();
                    return;
                }
                const choices = data.payload?.choices;
                if (choices?.text?.length) {
                    for (const seg of choices.text) {
                        if (typeof seg.content === 'string') reply += seg.content;
                    }
                } else if (typeof choices?.content === 'string') {
                    reply += choices.content;
                }
                if (choices?.status === 2 || data.header?.status === 2) {
                    resolve(reply);
                    ws.close();
                }
            };
            ws.onerror = (e) => { console.error('[Spark] WebSocket错误', e); reject(new Error('Spark WebSocket错误')); ws.close(); };
            ws.onclose = (evt) => { console.warn('[Spark] WebSocket关闭', evt.code, evt.reason, 'wasClean:', evt.wasClean); };
        });
    }

    private authQuery(encodeAuthorization = false): string {
        const date = new Date().toUTCString();
        const signatureOrigin = `host: ${this.host}\n` +
            `date: ${date}\n` +
            `GET ${this.path} HTTP/1.1`;
        const sha = CryptoJS.HmacSHA256(signatureOrigin, this.APISecret);
        const signature = CryptoJS.enc.Base64.stringify(sha);
        const authorizationOrigin = `api_key=\"${this.APIKey}\", algorithm=\"hmac-sha256\", headers=\"host date request-line\", signature=\"${signature}\"`;
        const authorization = btoa(authorizationOrigin);
        const authField = encodeAuthorization ? encodeURIComponent(authorization) : authorization;
        return `authorization=${authField}&date=${encodeURIComponent(date)}&host=${this.host}`;
    }
}

export const sparkChatService = new SparkChatService();


